#ifndef EGG_RENDERER_H
#define EGG_RENDERER_H

#include "Camera.h"
#include "Material.h"
#include "BlitEffect.h"
#include "RenderContext.h"
#include "OpaquePipeline.h"
#include "TransparentPipeline.h"
#include "GlobalGeometryGroup.h"
#include "GlobalGPUParamGroup.h"
#include "GlobalGPUProgramGroup.h"
#include "GlobalRenderTargetGroup.h"

namespace egg{

    class Renderer : public Singleton<Renderer>{
        friend class Singleton<Renderer>;
    public:
        void startup();
        void shutdown();
        void renderBegin();
        void render(Camera* _camera);
        void renderEnd();
        void addLight(Light* _light);
        void addDrawable(Drawable3D* _drawable);
    protected:
        Renderer();
        void renderShadows();
        void renderDPGs();
        void outputFinal();

        inline void setNormalMatrixParam(const mat4& _local2eye,bool _scaled){
            if(_scaled){
                gGPUParamGroup->mNormalMatrix->set(mat3(glm::transpose(glm::inverse(_local2eye))));
            }else{
                gGPUParamGroup->mNormalMatrix->set(mat3(_local2eye));
            }
        }
        inline void setLocal2EyeMatrixParam(const mat4& _local2eye){
            gGPUParamGroup->mLocal2EyeMatrix->set(_local2eye);
        }
    protected:
        RenderContext mContext;
        RenderQueue mDPGs[DP_Max];
        BlitEffect* mBlitEffect;
        OpaquePipeline* mOpaquePipeline;
        TransparentPipeline* mTransparentPipeline;
    };

    typedef shared_ptr<Renderer> RendererPtr;

}

#endif